package com.heima.comment.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.apis.article.IArticleClient;
import com.heima.apis.user.IUserClient;
import com.heima.apis.wemedia.IWemediaClient;
import com.heima.comment.pojos.*;
import com.heima.comment.service.CommentRepayService;
import com.heima.comment.service.CommentService;
import com.heima.common.constatns.HotArticleConstants;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.comment.dtos.*;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.message.UpdateArticleMess;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.utils.thread.AppThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Service
public class CommentRepayServiceImpl implements CommentRepayService {

    private final static Integer SELECT_COMMIT_NUM = 30;

    @Autowired
    private IArticleClient articleClient;

    @Autowired
    private IWemediaClient iWemediaClient;

    @Autowired
    private IUserClient userClient;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;

    /**
     * 保存评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult save(CommentRepaySaveDto dto) {

        //1.检查参数
        if (dto == null || dto.getCommentId() == null || StringUtils.isBlank(dto.getContent())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //2.必须登录后才能发表评论
        ApUser user = AppThreadLocalUtil.getUser();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //评论内容不能超过140字
        if (dto.getContent().length() > 140) {
            return ResponseResult.errorResult(501, "评论不得超过140个字");
        }
        //3.文本垃圾检测
        //3.1.阿里云敏感词审核  略
        //3.2.自管理敏感词审核
        if (handleSensitiveScan(dto.getContent())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "评论存在敏感词,请良好发言");
        }
        //4.保存评论
        ApUser dbUser = userClient.findUserById(user.getId());
        if (dbUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "当前登录信息有误");
        }
        ApCommentRepay apCommentRepay = new ApCommentRepay();
        apCommentRepay.setAuthorId(user.getId());
        apCommentRepay.setContent(dto.getContent());
        apCommentRepay.setCreatedTime(new Date());
        apCommentRepay.setCommentId(dto.getCommentId());
        apCommentRepay.setAuthorName(dbUser.getName());
        apCommentRepay.setUpdatedTime(new Date());
        apCommentRepay.setLikes(0);
        mongoTemplate.save(apCommentRepay);

        //5更新回复数量
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        apComment.setReply(apComment.getReply() + 1);
        mongoTemplate.save(apComment);

        UpdateArticleMess updateArticleMess = new UpdateArticleMess();
        updateArticleMess.setArticleId(apComment.getEntryId());
        updateArticleMess.setType(UpdateArticleMess.UpdateArticleType.COMMENT);
        updateArticleMess.setAdd(1);

        kafkaTemplate.send(HotArticleConstants.HOT_ARTICLE_SCORE_TOPIC,JSON.toJSONString(updateArticleMess));
        log.info("回复评论发送聚合消息成功");

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 加载评论列表
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult load(CommentRepayDto dto) {
        //1.检查参数
        if(dto == null || dto.getCommentId() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //2.加载数据
        Query query = Query.query(Criteria.where("commentId").is(dto.getCommentId()).and("createdTime").lt(dto.getMinDate()));
        query.with(Sort.by(Sort.Direction.DESC,"createdTime")).limit(SELECT_COMMIT_NUM);
        List<ApCommentRepay> list = mongoTemplate.find(query, ApCommentRepay.class);

        //3.数据封装返回
        //3.1 用户未登录
        ApUser user = AppThreadLocalUtil.getUser();
        if(user == null){
            return ResponseResult.okResult(list);
        }

        //3.2 用户已登录
        //需要查询当前评论中哪些数据被点赞了
        List<String> idList = list.stream().map(x -> x.getId()).collect(Collectors.toList());
        Query query1 = Query.query(Criteria.where("commentRepayId").in(idList).and("authorId").is(user.getId()));
        List<ApCommentRepayLike> apCommentRepayLikes = mongoTemplate.find(query1, ApCommentRepayLike.class);
        if(apCommentRepayLikes == null || apCommentRepayLikes.size() == 0 ){
            return ResponseResult.okResult(list);
        }

        List<CommentRepayVo> resultList = new ArrayList<>();
        list.forEach(x->{
            CommentRepayVo vo = new CommentRepayVo();
            BeanUtils.copyProperties(x,vo);
            for (ApCommentRepayLike apCommentRepayLike : apCommentRepayLikes) {
                if(x.getId().equals(apCommentRepayLike.getCommentRepayId())){
                    vo.setOperation((short)0);
                    break;
                }
            }
            resultList.add(vo);
        });

        return ResponseResult.okResult(resultList);
    }

    /**
     * 点赞评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentRepayLikeDto dto) {
        //检查参数
        if (Objects.isNull(dto) || dto.getCommentRepayId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //判断是否登录
        ApUser user = AppThreadLocalUtil.getUser();
        if (Objects.isNull(user)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //查询点赞的回复评论信息
        ApCommentRepay apCommentRepay = mongoTemplate.findById(dto.getCommentRepayId(), ApCommentRepay.class);
        //点赞
        if (apCommentRepay != null && dto.getOperation() == 0) {
            //更新评论点赞数量
            apCommentRepay.setLikes(apCommentRepay.getLikes()+1);
            mongoTemplate.save(apCommentRepay);

            //保存评论点赞数据
            ApCommentRepayLike apCommentRepayLike = new ApCommentRepayLike();
            apCommentRepayLike.setCommentRepayId(apCommentRepay.getId());
            apCommentRepayLike.setAuthorId(user.getId());
            apCommentRepayLike.setOperation(dto.getOperation());
            mongoTemplate.save(apCommentRepayLike);
        }else {    //取消点赞
            //更新评论点赞数量
            int tmp = apCommentRepay.getLikes()-1;
            tmp = tmp < 1 ? 0 : tmp;
            apCommentRepay.setLikes(tmp);
            mongoTemplate.save(apCommentRepay);

            //删除评论点赞
            Query query = Query.query(Criteria.where("commentRepayId").is(apCommentRepay.getId()).and("authorId").is(user.getId()));
            mongoTemplate.remove(query,ApCommentRepayLike.class);
        }

        //4.返回点赞
        Map<String,Object> result = new HashMap<>();
        result.put("likes",apCommentRepay.getLikes());
        return ResponseResult.okResult(result);
    }


    /**
     * 自定义敏感词过滤
     *
     * @param comment
     * @return
     */
    private boolean handleSensitiveScan(String comment) {

        boolean flag = false;
        //获取所有的敏感词
        ResponseResult responseResult = iWemediaClient.getWmSensitives();

        if (responseResult.getCode().equals(200) && responseResult.getData() != null) {
            String string = JSON.toJSONString(responseResult.getData());
            List<WmSensitive> wmSensitives = JSON.parseArray(string, WmSensitive.class);
            if (wmSensitives != null && wmSensitives.size() > 0) {
                List<String> collect = wmSensitives.stream().map(WmSensitive::getSensitives).collect(Collectors.toList());
                //初始化敏感词库
                SensitiveWordUtil.initMap(collect);
                //看出文章或（图片中的文字）中是否有敏感词
                Map<String, Integer> map = SensitiveWordUtil.matchWords(comment); //标题也需判断
                if (map.size() > 0) {
                    flag = true;
                    log.error("当前评论内容存在敏感信息存在敏感词{}", map);
                }
            }
        }
        return flag;
    }
}
